package com.ngc.mall.logic;

import com.ngc.mall.bo.SkuOrderBO;
import com.ngc.mall.common.configure.exception.BusinessException;
import com.ngc.mall.common.configure.response.ResponseCode;
import com.ngc.mall.core.enumeration.CouponType;
import com.ngc.mall.core.money.IMoneyDiscount;
import com.ngc.mall.domain.CouponDomain;
import com.ngc.mall.util.CommonUtil;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 * 优惠券校验类
 * @author: chenxiaolin
 * @date 2023/8/25 10:37
**/
public class CouponChecker {
    private CouponDomain coupon;
    private IMoneyDiscount iMoneyDiscount;
    public CouponChecker(CouponDomain couponDomain,IMoneyDiscount iMoneyDiscount) {
        this.coupon=couponDomain;
    }

    public void canUsed(){
        LocalDateTime now=LocalDateTime.now();
        Boolean canUse= CommonUtil.isInTimeLine(now,coupon.getStartDate(),coupon.getEndDate());
        if(!canUse){
            throw new BusinessException(ResponseCode.COUPON_EXPIRED);
        }
    }

    public void isOk( BigDecimal serverTotalPrice,List<SkuOrderBO> skuOrderBOList){
        BigDecimal orderCategoryPrice=new BigDecimal("0");

        if(coupon.getWholeStore()){
            orderCategoryPrice=serverTotalPrice;
        }else{
            List<Long> categoryList=coupon.getCategoryList().stream().map(c->c.getId()).collect(Collectors.toList());
            orderCategoryPrice=getTotalPriceByCategoryList(skuOrderBOList, categoryList);
        }
        this.couponUsedOk(coupon,orderCategoryPrice);
    }

    public void couponUsedOk(CouponDomain coupon,BigDecimal orderFinalTotalPrice){
        switch (CouponType.toType(coupon.getType())){
            case FULL_MINUS:
            case FULL_OFF:
               int compare =coupon.getFullMoney().compareTo(orderFinalTotalPrice);
                if(compare>0){
                    throw new BusinessException(ResponseCode.COUPON_ERROR);
                }
            case NO_THRESHOLD_MINUS:
                break;
            default:
                throw new BusinessException(ResponseCode.COUPON_ERROR);
        }

    }

    /**
     * 校验订单提交的最终金额
     * @param orderFinalTotalPrice
     * @param serverTotalPrice
     */
    public void finalTotalPriceIsOk(BigDecimal orderFinalTotalPrice,BigDecimal serverTotalPrice){
        BigDecimal serverFinalTotalPrice=new BigDecimal("0");
        switch (CouponType.toType(coupon.getType())){
            case FULL_MINUS:
            case NO_THRESHOLD_MINUS:
                serverFinalTotalPrice=serverTotalPrice.subtract(coupon.getMinus());
                if(serverFinalTotalPrice.compareTo(new BigDecimal("0"))<=0){
//                    throw new BusinessException();
                    System.out.println("最终支付金额小于0");
                }
                break;
            case FULL_OFF:
                serverFinalTotalPrice=discount(serverTotalPrice,coupon.getRate());
                break;
            default:
                throw new BusinessException();
        }
        int compare=serverFinalTotalPrice.compareTo(orderFinalTotalPrice);
        if(compare!=0){
            throw new BusinessException();
        }

    }

    public BigDecimal discount(BigDecimal original,BigDecimal discount)
    {
        BigDecimal actualMoney = original.multiply(discount);
        BigDecimal finalMoney = actualMoney.setScale(2, RoundingMode.UP);
        return finalMoney;
    }

    public BigDecimal getTotalPriceByCategory(List<SkuOrderBO> skuOrderBOList, Long cid){
        BigDecimal sum=skuOrderBOList.stream().filter(s->s.getCategoryId().equals(cid)).map(SkuOrderBO::getTotalPrice).reduce(BigDecimal::add).orElse(new BigDecimal("0"));
        return sum;
    }

    public BigDecimal getTotalPriceByCategoryList(List<SkuOrderBO> skuOrderBOList, List<Long> categoryList){
        BigDecimal totalSum=categoryList.stream().map(c->getTotalPriceByCategory(skuOrderBOList,c)).reduce(BigDecimal::add).orElse(new BigDecimal("0"));
        return totalSum;
    }
}
